package com.practice.system.service.impl;

import com.practice.jwt.JwtUtils;
import com.practice.system.mapper.UserMapper;
import com.practice.system.pojo.User;
import com.practice.system.service.UserService;
import com.practice.utils.R;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Objects;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    JwtUtils jwtUtils;

    @Override
    public User getUserByAccountName(String accountName) {
        User user = userMapper.getUser(accountName);
        return user;
    }

    @Override
    public R login(User user) {
        //使用security提供的用户认证
        //1.封装成security需要的包
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getAccountName(), user.getPassword());
        //2.使用authenticationManager进行用户验证
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

//        认证失败
        if (Objects.isNull(authenticate)) throw new UsernameNotFoundException("账户名或密码错误");

        //认证通过,使用账户名生产jwt
        User principal = (User) authenticate.getPrincipal();
        String accountName = principal.getUsername();
        HashMap<String, Object> payload = new HashMap<>();
        payload.put(Claims.SUBJECT, accountName);
        String token = jwtUtils.generateToken(payload);

        HashMap<String, Object> data = new HashMap<>();
        data.put("token", token);
        principal.setPassword(null);
        data.put("info", principal);
        return R.ok().put("data", data);
    }

    @Override
    public R sign(User user) {
        UserDetails details = userMapper.getUser(user.getAccountName());
        if (details != null) {
            return R.error("用户已经存在");
        }
        String pwd = passwordEncoder.encode(user.getPassword());
        user.setPassword(pwd);
        user.setUserType(0);
        Integer insert = userMapper.insert(user);
        if (insert == 1) {
            return R.ok("注册成功");
        }
        return R.error("注册失败");
    }
}
